table of contents
STRACE(1) | General Commands Manual | STRACE(1) |
NAZWA¶
strace - śledź wywołania systemowe i sygnały
SKŁADNIA¶
strace [ -dffhiqrtttTvxx ] [ -akolumna ] [ -ewyraż ] ... [ -oplik ] [ -ppid ] ... [ -srozmiarnapisu ] [ -uużytkownik ] [ komenda [ arg ... ] ]
strace -c [ -ewyraż ] ... [ -Owydatki ] [ -Ssortuj ] [ komenda [ arg ... ] ]
OPIS¶
W najprostszym przypadku, strace wykonuje zadaną komendę `komenda' aż się ona nie skończy. Strace przechwytuje i nagrywa wywołania systemowe, dokonane przez proces, oraz sygnały, które do niego dotarły. Nazwa każdego wywołania, oraz jego argumenty, są wypisywane na wyjście standardowe błędu, lub do pliku podanego w opcji -o.
strace jest użytecznym narzędziem diagnostyki, debuggowania. Administratorzy systemów, diagnostycy i napotykacze problemów zauważą, że jest nieocenione dla rozwiązywania problemów z programami, których źródeł nie ma wprost dostępnych. Strace bowiem nie potrzebuje rekompilacji aby go użyć. Studenci, hackerzy i ogólnie zainteresowani zauważą, że z śledzenia wywołań systemowych można się wiele nauczyć o systemie. Programiści zauważą, że skoro wywołania systemowe i sygnały są zdarzeniami zachodzącymi na interfejsie użytkownik/jądro, to ich bliska obserwacja może być bardzo użyteczna do izolowania błędów, sprawdzania czystości i próbowania wyłapywania ulotnych warunków.
Każda śledzona linia zawiera nazwę wywołania systemowego, za którą następują jego argumenty, otoczone nawiasami, oraz jego wartość zwracana. Przykładowe śledzenie komendy ``cat /dev/null'' daje:
open("/dev/null", O_RDONLY) = 3
Do błędów (zwykle wartości zwracane -1) dopisywany jest symbol errno i napis błędu.
open("/foo/bar", O_RDONLY) = -1 ENOENT (No such file or directory)
Sygnały są drukowane jako symbol, oraz napis sygnału. Fragment śledzenia i przerwania komendy ``sleep 666'' to:
sigsuspend([] <unfinished ...> --- SIGINT (Interrupt) --- +++ killed by SIGINT +++
Argumenty są namiętnie drukowane w formie symbolicznej. Przykład ten pokazuje dokonanie przekierowania ``>>xyzzy'':
open("xyzzy", O_WRONLY|O_APPEND|O_CREAT, 0666) = 3
Tutaj, wymienione trzy argumenty z open są zdekodowane poprzez rozbicie argumentu flagi na jego bitowe składniki i wydrukowanie ich tradycyjnych nazw, oraz wartości ósemkowej praw. Choć tradycyjne, lub natywne używanie różni się od ANSI lub POSIX, to te ostatnie formy są jednak preferowane. W niektórych wypadkach, wyjście strace może być bardziej czytelne niż źródła.
Wskaźniki struktury są dereferencjonowane, a członkowie są odpowiednio wyświetlani. We wszystkich wypadkach argumenty są formatowane w stylu C. Na przykład, istota komendy ``ls -l /dev/null'' jest przechwytywana jako:
lstat("/dev/null", {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 3), ...}) = 0
Zauważ, jak zdereferencjonowano argument `struct stat' i jak wyświetlono każdego członka. Praktycznie, zauważ jak ostrożnie został zdekodowany członek st_mode na jego maskę bitową. Zauważ też, że w tym przykładzie, pierwszym argumentem lstat jest wejście wywołania systemowego, a drugim jego wyjście. Ponieważ argumenty wyjściowe nie są modyfikowane jeśli wywołanie zawiedzie, argumenty nie zawsze mogą zostać zdereferencjonowane. Na przykład próba ``ls -l'' na nieistniejącym pliku da następującą linię:
lstat("/foo/bar", 0xb004) = -1 ENOENT (No such file or directory)
Wskaźniki znakowe są dereferencjonowane i wyświetlane jako napisy C. Niedrukowalne znaki są reprezentowane w kodach eskejpowych. Drukowanych jest tylko pierwszych rozmiarnapisu (domyślnie 32) bajtów napisu; dłuższe napisy mają za zamykającym cytatem dołączone wielokropki. Oto przykład ``ls -l'', gdzie funkcja biblioteki getpwuid odczytuje plik z hasłem:
read(3, "root::0:0:System Administrator:/"..., 1024) = 422
Podczas gdy struktury są notowane przy użyciu nawiasów klamrowych, zwykłe wskaźniki i tablice są drukowane przy użyciu nawiasów kwadratowych, z przecinkami oddzielającymi elementy. Oto przykład wywołania komendy ``id'' na systemie z dodatkowymi id grup:
getgroups(32, [100, 0]) = 2
Z drugiej strony, zbiory bitowe też są pokazywane w nawiasach kwadratowych, lecz elementy są oddzielane tylko przez spację. Oto powłoka, przygotowująca się do wywołania komendy zewnętrznej:
sigprocmask(SIG_BLOCK, [CHLD TTOU], []) = 0
Drugi argument jest zbiorem bitowym dwóch sygnałów, SIGCHLD i SIGTTOU. W niektórych wypadkach, zbiory bitowe są tak pełne, że bardziej sensowne jest drukowanie nieustawionych elementów. W takiej sytuacji zbiór jest poprzedzony tyldą, jak w następującym przykładzie:
sigprocmask(SIG_UNBLOCK, ~[], NULL) = 0
Drugi argument wskazuje, że ustawiono cały zestaw sygnałów.
OPCJE¶
- -c
- Zliczaj czas, wywołania i błędy dla każdego wywołania systemowego i zgłoś na końcu raport.
- -d
- Przekaż na stderr wyjście debuggowe strace.
- -f
- Śledź procesy potomne, tworzone prze obecnie śledzone procesy, jako rezultat wywołania systemowego fork(2). Nowe procesy są dołączane tak szybko, jak szybko zostaje uzyskany ich pid (poprzez wartość zwracaną fork(2) w procesie rodzicielskim). Oznacza to, że takie dzieci mogą na chwilę być niekontrolowane (szczególnie w wypadku vfork(2)), aż rodzic nie zostanie znów wyshedulowany do dokończenia wywołania (v)fork(2). Jeśli rodzic zdecyduje zaczekać (wait(2)) na dziecko, które obecnie jest śledzone, zostaje on zawieszony aż potomek się nie zakończy.
- -ff
- opcja -o nazwapliku będzie działać, śledzenie każdego procesu jest zapisywane do nazwapliku.pid, gdzie pid jest numerycznym identyfikatorem procesu.
- -F
- Na SunOS 4.x opcja ta powoduje próbę podążania za vforkami poprzez triki dynamicznego linkowania. W przeciwnym wypadku, vforki nie będą śledzone, nawet z podaną opcją -f.
- -h
- Wydrukuj podsumowanie pomocy.
- -i
- Drukuj podczas wywołania systemowego wskaźnik instrukcji.
- -q
- Zahamuj komunikaty o przyłączaniu, odłączaniu, etc. Dzieje się to automatycznie gdy wyjście jest przekierowywane do pliku, a komenda jest wykonywana bezpośrednio, zamiast przyłączania.
- -r
- Drukuj względny timestamp podczas każdego wywołania systemowego. Nagruwa to różnicę czasu między początkami kolejnych wywołań systemowych.
- -t
- Poprzedź każdą linię trace czasem dnia.
- -tt
- Jeśli podane dwukrotnie, wydrukowany czas włącza mikrosekundy.
- -ttt
- Jeśli podane trzykrotnie, wydrukowany czas włącza mikrosekundy, a prowadząca porcja będzie zawierać liczbę sekund od epoki.
- -T
- Pokaż czas spędzony na wywołaniach systemowych. Nagrywa to różnice czasowe między początkiem i końcem każdego wywołania systemowego.
- -v
- Drukuj nieskrócone wersje wywołań environment, stat, termios, itp. Struktury te są wspólne w wywołaniach, więc domyślne zachowanie wyświetla rozsądny podzbiór członków. Gdy uzyjesz tej opcji, wyświetlone zostanie wszystko.
- -V
- Wydrukuj numer wersji strace.
- -x
- Drukuj wszystkie niedrukowalne napisy w formacie szesnastkowym.
- -xx
- Drukuj wszystkie napisy w formacie szesnastkowym.
- -a kolumna
- Justuj zwracane wartości w konkretnej kolumnie (domyślnie 40).
- -e wyraż
- Wyrażenie kwalifikujące, określające
które zdarzenia śledzić, lub jak je
śledzić. Formatem wyrażenia jest:
[kwalifikator=][!]wartość1[,wartość2]...
gdzie kwalifikator jest jednym z trace, abbrev, verbose, raw, signal, read, lub write, a wartość jest zależnaym od kwalifikatora symbolem, lub liczbą. Domyślnym kwalifikatorem jest trace (śledź). Użycie wykrzyknika neguje zbiór wartości. Na przykład -eopen oznacza -e trace=open, co z kolei oznacza, by śledzić tylko wywołania systemowe open. Odwrotnie, -etrace=!open oznacza, by śledzić wszystkie wywołania poza wywołaniami open. Dodatkowo, istnieją specjalne wartości all (wszystko) i none (nic).
Zauważ, że niektóre powłoki używają wykrzyknika dla rozszerzenia histori; nawet wewnątrz cytowanych argumentów. Jeśli tak będzie, musisz wyeskejpować wykrzyknik odwrotnym ukośnikiem.
- -e trace=zbiór
- Śledź tylko podany zbiór wywołań systemowych. Opcja -c jest użyteczna dla określania, które wywołania systemowe mogą być użyteczne do śledzenia. Na przykład trace=open,close,read,write oznacza, by śledzić tylko te cztery wywołania systemowe. Uważaj z wyciąganiem wniosków o ramce użytkownik/jądro jeśli monitorujesz tylko podzbiór używanych wywołań systemowych. Domyślnie, trace=all.
- -e trace=file
- Śledź wszystkie wywołania systemowe, które biorą nazwę pliku jako argument. Możesz myśleć o tym jak o skrócie dla -e trace=open,stat,chmod,unlink,... co może być użyteczne dla sprawdzenia, które pliki są ważne dla procesu. Co więcej, użycie skrótu zapewni, że przypadkiem nie zapomnisz dołączyć wywołania w rodzaju lstat.
- -e trace=process
- Śledź wszystkie wywołania systemowe, które zajmują się zarządzaniem procesami. Jest to przydatne do obserwowania kroków fork, wait i exec procesu.
- -e trace=network
- Śledź wszystkie wywołania związane z siecią.
- -e trace=signal
- Śledź wszystkie wywołania związane z sygnałami.
- -e trace=ipc
- Śledź wszystkie wywołania związane z IPC.
- -e abbrev=zbiór
- Skróć wyjście przez niedrukowanie każdego członka dużych struktur. Domyślnie abbrev=all. Opcja -v ma efekt abbrev=none.
- -e verbose=zbiór
- Dereferencjuj struktury podanego zestawu wywołań systemowych. Domyślnie jest verbose=all.
- -e raw=zbiór
- Drukuj czyste, niezdekodowane argumenty podanych wywołań systemowych. Opcja te powoduje, że wszystkie argumenty są drukowane szesnastkowo. Jest to najbardziej użyteczne, jeśli nie ufasz dekodowaniu, lub jeśli potrzebujesz znać właściwe wartości numeryczne argumentów.
- -e signal=zbiór
- Śledź tylko podany zbiór sygnałów. Domyślnie jest signal=all. Na przykład signal=!SIGIO (lub signal=!io) powoduje, że sygnały SIGIO nie będą śledzone.
- -e read=zbiór
- Dokonuj zrzutów szesnastkowych i ascii wszystkich danych odczytywanych z deskryptorów podanych w zbiorze. Na przykład, by zobaczyć co dzieje się na wejściu deskryptorów 3, 5, użyj: -e read=3,5. Zauważ, że jest to niezależne od normalnego śledzenia wywołania read, które jest kontrolowane opcją -e trace=read.
- -e write=zbiór
- Dokonuj zrzutów szesnastkowych i ascii wszystkich danych zapisywanych do deskryptorów podanych w zbiorze. Na przykład, by zobaczyć co dzieje się na wyjściu deskryptorów 3, 5, użyj: -e write=3,5. Zauważ, że jest to niezależne od normalnego śledzenia wywołania write, które jest kontrolowane opcją -e trace=write.
- -o nazwapliku
- Zapisuj wyjście śledzenia do pliku nazwapliku, a nie na standardowy błąd. Użyj nazwapliku.pid jeśli użyto opcji -ff. Jesli argument zaczyna się od `|' lub od `!', reszta argumentu traktowana jest jak komenda i całe wyjście jest do niej przesyłane. Jest to przydatne dla przekierowywania wyjścia debuggowego, nie dotykając przekierowań normalnego wyjścia programu.
- -O wydatki
- Ustaw wydatki na śledzenie wywołań systemowych na wydatki mikrosekund. Jest to użyteczne dla przeciążenia domyślnej heurystyki dla zgadywania ile czasu jest spędzanego na czystym mierzeniu podczas timingowaniu wywołań systemowych przy użyciu opcji -c. Dokładność heurystyki może być ocenione przez timingowanie danego programu bez śledzenia i porównanie zebranego czasu wywołań systemowych do całkowitego, wydanego przy użyciu -c .
- -p pid
- Podwieś się do procesu o podanym identyfikatorze ID pid i rozpocznij śledzenie. Śledzenie może być zakończone w dowolnym momencie przez przerwanie z klawiatury (CTRL-C). strace odpowie przez odwieszenie się od śledzonego procesu(ów), pozostawiając go (je) w spokoju. Do podwieszenia się do kolejnych 32 procesów, można używać wielu opcji -p, jako uzupełnienie komendy komenda (która jest opcjonalna, jeśli podano przynajmniej jedną opcję -p).
- -s wielkośćnapisu
- Podaj maksymalną długość drukowanego napisu (domyślnie 32). Zauważ, że nazwy plików nie są uważane za napisy i zawsze są drukowane w całości.
- -S sortuj
- Sotruj wyjściowy histogram opcji -c według podanego kryterium. Legalnymi wartościami są time, calls, name, i nothing (domyślne to time).
- -u użytkownik
- Uruchom komendę z userid i groupid, oraz dodatkowymi grupami użytkownika. Opcja ta jest użyteczna tylko podczas pracy z roota i umożliwia właściwe wywołanie binariów z ustawionymi sgid/suid. Bez tej opcji, programy suid/sgid są wywoływane bez efektywnych przywilejów.
INSTALACJA SETUID¶
Jeśli strace jest zainstalowane z suid root, to użytkownik wywołujący będzie mógł się podłączyć i śledzić procesy dowolnego innego użytkownika. Dodatkowo, programy suid i sgid będą wywoływane i śledzonez właściwymi efektywnymi przywilejami. Ponieważ robić to powinni tylko zaufani użytkownicy z przywilejami roota, takie instalowanie strace ma sens tylko, jeśli użytkownicy uprawnieni do jego wywoływania mają odpowiednie przywileje. Na przykład sensowne jest instalowanie specjalnej wersji strace z prawami `rwsr-xr--', dla użytkownika root i grupy trace, gdzie członkowie grupy trace są zaufanymi osobami. Jeśli używasz tej właściwości, pamiętej by zainstalować niesuidowaną wersję strace dla zwykłych luserów.
ZOBACZ TAKŻE¶
UWAGI¶
Szkoda, że w systemach z bibliotekami dzielonym jest produkowanych tyle śmieci podczas śledzenia.
Jest dobrze myśleć o wejściach i wyjściach wywołań systemowych jak o przepływie danych między przestrzenią użytkownika i jądra. Ponieważ przestrzeń użytkownika i przestrzeń jądra są oddzielone granicą ochrony adresów, można czasem wyciągać wnioski dedukcyjne o zachowaniu procesu na podstawie wartości wejścia i wyjścia.
W niektórych wypadkach wywołanie systemowe może różnić się od udokumentowanego zachowania, lub mieć inną nazwę. Na przykład na systemach zgodnych z System V, rzeczywiste wywołanie time(2) nie pobiera argumentu, a funkcja stat nazywana jest xstat i bierze dodatkowy argument. Różnice te są normalne, lecz uczulone charakterystyki interfejsu wywołań systemowych są obsługiwane przez wrappery biblioteki C.
Na niektórych platformach proces, który ma załączone śledzenie wywołań systemowych z opcją -p otrzyma SIGSTOP. Sygnał ten może przerwać wywołanie systemowe, które nie jest restartowalne. Może to mieć nieprzewidziane efekty na procesie, jeśli proces nie podejmuje działań do restartowania wywołania systemowego.
BŁĘDY¶
Programy, które używają bitu setuid nie będą miały efektywnych uprawnień użytkownika podczas śledzenia.
Śledzony proces ignoruje SIGSTOP (poza platformami SVR4).
Śledzony proces, próbujący zablokować SIGTRAP otrzyma SIGSTOP w próbie kontynuacji śledzenia.
Śledzony program działa powoli.
Śledzone procesy, które schodzą z komendy komenda mogą zostać pozostawione po sygnale przerwania (CTRL-C).
Pod Linuksem, śledzenie procesu init jest zabronione.
Opcja -i jest słabo wspierana.
HISTORIA¶
strace Oryginalny strace został napisany przez Paula Kranenburga dla SunOS, który został zinspirowany narzędziem trace. Wersja SunOS strace została przeniesiona na Linuksa i rozszerzona przez Branko Lankestera, który również napisał wsparcie jądra Linuksa. Mimo, że Paul w 1992 wypuścił wersję 2.5 strace, prace Branko opierały się na strace 1.5 z 1991. W 1993 Rick Sladkey połączył zmiany strace 2.5 z SunOS ze zmianami wersji linuksowej, dodał wiele właściwości z truss'a z SVR4 i wydał wersję strace, która działała na obydwu platformach. W 1994 Rick przeportował strace na SVR4 i Solaris, oraz napisał wsparcie automatycznej konfiguracji. W 1995 przeportował strace na Irixa i zmęczył się pisaniem o sobie w trzeciej osobie.
PROBLEMY¶
Problemy związane ze strace powinny być zgłaszane do obecnego opiekuna strace, którym jest Rick Sladkey <jrs@world.std.com>.
96/02/13 |